package com.bitin.adorn.modules.transaction.service;

import com.bitin.adorn.modules.account.PrepaidTaxResult;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class BillService {
    /**
     * 小数点后保留位数，2位，四舍五入
     */
    private static final int DIGIT_NUMBER_AFTER_DOT = 2;
    /**
     * 起征点
     */
    private static final BigDecimal DEDUCTION = BigDecimal.valueOf(5000);

    /**
     * 本期应预扣预缴税额 = (累计预扣预缴应纳税所得额 × 预扣率 − 速算扣除数) − 累计减免税额 − 累计已预扣预缴税额
     *
     * @名词解释 cumulativeExemptIncome             累计免税收入
     * @名词解释 cumulativeSpecialDeductions        累计专项扣除
     * @名词解释 cumulativeAdditionalDeductions     累计专项附加扣除
     * @名词解释 cumulativeOtherDeductions          累计依法确定的其他扣除
     * @名词解释 cumulativeReliefTax                累计减免税额
     *
     * @param cumulativeIncome      累计收入
     * @param cumulativeDeductions  累计减除费用
     * @param cumulativePrepaidTax  累计已预扣预缴税额
     * @return
     */
    private PrepaidTaxResult calculateCurrentPeriodIndividualIncomeTax(BigDecimal cumulativeIncome, BigDecimal cumulativeDeductions, BigDecimal cumulativePrepaidTax){
        // 累计预扣预缴应纳税所得额 = 累计收入 - 累计免税收入 - 累计减除费用 - 累计专项扣除 - 累计专项附加扣除 - 累计依法确定的其他扣除
        BigDecimal cumulativeTaxableIncome = cumulativeIncome.subtract(cumulativeDeductions);
        if (cumulativeTaxableIncome.compareTo(BigDecimal.ZERO) == -1 || cumulativeTaxableIncome.compareTo(BigDecimal.ZERO) == 0) {
            return PrepaidTaxResult.empty();
        }

        // 税率
        BigDecimal taxRate;
        // 速算扣除数
        BigDecimal quickDeduction;

        if (cumulativeTaxableIncome.compareTo(BigDecimal.valueOf(36000)) == -1 || cumulativeTaxableIncome.compareTo(BigDecimal.valueOf(36000)) == 0) {
            taxRate = BigDecimal.valueOf(0.03);
            quickDeduction = BigDecimal.ZERO;
        } else if (cumulativeTaxableIncome.compareTo(BigDecimal.valueOf(144000)) == -1 || cumulativeTaxableIncome.compareTo(BigDecimal.valueOf(144000)) == 0) {
            taxRate = BigDecimal.valueOf(0.1);
            quickDeduction = BigDecimal.valueOf(2520);
        } else if (cumulativeTaxableIncome.compareTo(BigDecimal.valueOf(300000)) == -1 || cumulativeTaxableIncome.compareTo(BigDecimal.valueOf(300000)) == 0) {
            taxRate = BigDecimal.valueOf(0.2);
            quickDeduction = BigDecimal.valueOf(16920);
        } else if (cumulativeTaxableIncome.compareTo(BigDecimal.valueOf(420000)) == -1 || cumulativeTaxableIncome.compareTo(BigDecimal.valueOf(420000)) == 0) {
            taxRate = BigDecimal.valueOf(0.25);
            quickDeduction = BigDecimal.valueOf(31920);
        } else if (cumulativeTaxableIncome.compareTo(BigDecimal.valueOf(660000)) == -1 || cumulativeTaxableIncome.compareTo(BigDecimal.valueOf(660000)) == 0) {
            taxRate = BigDecimal.valueOf(0.3);
            quickDeduction = BigDecimal.valueOf(52920);
        } else if (cumulativeTaxableIncome.compareTo(BigDecimal.valueOf(960000)) == -1 || cumulativeTaxableIncome.compareTo(BigDecimal.valueOf(960000)) == 0) {
            taxRate = BigDecimal.valueOf(0.35);
            quickDeduction = BigDecimal.valueOf(85920);
        } else {
            taxRate = BigDecimal.valueOf(0.45);
            quickDeduction = BigDecimal.valueOf(181920);
        }

        // 本期应预扣预缴税额 = (累计预扣预缴应纳税所得额 x 预扣率 - 速算扣除数)-累计已预扣预缴税额
        BigDecimal currentPeriodTax = cumulativeTaxableIncome.multiply(taxRate).subtract(quickDeduction).subtract(cumulativePrepaidTax);
        return PrepaidTaxResult.builder()
            .taxableIncome(cumulativeTaxableIncome)
            .taxRate(taxRate)
            .quickDeduction(quickDeduction)
            .tax(currentPeriodTax)
            .build();
    }

    private PrepaidTaxResult calculateIndividualIncomeTax(BigDecimal income) {
        // 应纳税所得额 = 月度收入 - 5000元(免征额) - 专项扣除(五险一金等) - 专项附加扣除 - 依法确定的其他扣除
        BigDecimal taxableIncome = income.subtract(DEDUCTION);
        if (taxableIncome.compareTo(BigDecimal.ZERO) == -1 || taxableIncome.compareTo(BigDecimal.ZERO) == 0) {
            return PrepaidTaxResult.empty();
        }

        // 税率
        BigDecimal taxRate;
        // 速算扣除数
        BigDecimal quickDeduction;

        if (taxableIncome.compareTo(BigDecimal.valueOf(3000)) == -1 || taxableIncome.compareTo(BigDecimal.valueOf(3000)) == 0) {
            taxRate = BigDecimal.valueOf(0.03);
            quickDeduction = BigDecimal.ZERO;
        } else if (taxableIncome.compareTo(BigDecimal.valueOf(12000)) == -1 || taxableIncome.compareTo(BigDecimal.valueOf(12000)) == 0) {
            taxRate = BigDecimal.valueOf(0.1);
            quickDeduction = BigDecimal.valueOf(210);
        } else if (taxableIncome.compareTo(BigDecimal.valueOf(25000)) == -1 || taxableIncome.compareTo(BigDecimal.valueOf(25000)) == 0) {
            taxRate = BigDecimal.valueOf(0.2);
            quickDeduction = BigDecimal.valueOf(1410);
        } else if (taxableIncome.compareTo(BigDecimal.valueOf(35000)) == -1 || taxableIncome.compareTo(BigDecimal.valueOf(35000)) == 0) {
            taxRate = BigDecimal.valueOf(0.25);
            quickDeduction = BigDecimal.valueOf(2660);
        } else if (taxableIncome.compareTo(BigDecimal.valueOf(55000)) == -1 || taxableIncome.compareTo(BigDecimal.valueOf(55000)) == 0) {
            taxRate = BigDecimal.valueOf(0.3);
            quickDeduction = BigDecimal.valueOf(4410);
        } else if (taxableIncome.compareTo(BigDecimal.valueOf(80000)) == -1 || taxableIncome.compareTo(BigDecimal.valueOf(80000)) == 0) {
            taxRate = BigDecimal.valueOf(0.35);
            quickDeduction = BigDecimal.valueOf(7160);
        } else {
            taxRate = BigDecimal.valueOf(0.45);
            quickDeduction = BigDecimal.valueOf(15160);
        }

        // 应纳税额 = 应纳税所得额 × 税率 - 速算扣除数
        BigDecimal currentPeriodTax = taxableIncome.multiply(taxRate).subtract(quickDeduction);
        return PrepaidTaxResult.builder()
            .taxableIncome(taxableIncome)
            .taxRate(taxRate)
            .quickDeduction(quickDeduction)
            .tax(currentPeriodTax)
            .build();
    }

    /**
     * 劳务报酬所得
     * <p>
     * 计算方式理解：
     * <h1>
     * 税率适应于应纳税所得额，而不是税前总收入。
     * 收入小于等于800部分，不计税。
     * 收入大于800且小于等于4000的部分，应纳税所得额 = 总收入-800。
     * 收入大于等于4000部分，应纳税所得额 = 总收入 x 0.8。
     * <p>
     * 应纳税所得额小于等于20000，适用于税率20%。
     * 应纳税所得额大于20000且小于等于50000，适用于税率30%，速扣系数2000。
     * 应纳税所得额大于50000，适用于税率40%，速扣系数7000。
     * <h1/>
     *
     * @param income
     * @return 应缴税额
     */
    public PrepaidTaxResult calculateLaborTax(BigDecimal income) {
        // 应纳税所得额
        BigDecimal taxableIncome;
        // 税率
        BigDecimal taxRate;
        // 速算扣除数
        BigDecimal quickDeduction;

        if (income.compareTo(BigDecimal.valueOf(4000)) == -1 || income.compareTo(BigDecimal.valueOf(4000)) == 0) {
            // 每次收入不超过4000元，应纳税所得额 = 每次劳务所得 - 800元
            taxableIncome = income.subtract(BigDecimal.valueOf(800));
        } else {
            // 每次收入超过4000元，应纳税所得额 = 每次劳务所得 × (1-20%)
            taxableIncome = income.multiply(BigDecimal.ONE.subtract(BigDecimal.valueOf(0.2)));
        }

        if (taxableIncome.compareTo(BigDecimal.ZERO) == -1 || taxableIncome.compareTo(BigDecimal.ZERO) == 0) {
            return PrepaidTaxResult.empty();
        }

        if (taxableIncome.compareTo(BigDecimal.valueOf(20000)) == -1 || taxableIncome.compareTo(BigDecimal.valueOf(20000)) == 0) {
            taxRate = BigDecimal.valueOf(0.2);
            quickDeduction = BigDecimal.ZERO;
        } else if (income.compareTo(BigDecimal.valueOf(50000)) == -1 || income.compareTo(BigDecimal.valueOf(50000)) == 0) {
            taxRate = BigDecimal.valueOf(0.3);
            quickDeduction = BigDecimal.valueOf(2000);
        } else {
            taxRate = BigDecimal.valueOf(0.4);
            quickDeduction = BigDecimal.valueOf(7000);
        }

        // 应纳税额 = 应纳税所得额 × 适用税率 - 速算扣除数
        BigDecimal currentPeriodTax = taxableIncome.multiply(taxRate).subtract(quickDeduction);
        // 税后收入
        BigDecimal incomeAfterTax = income.subtract(currentPeriodTax).setScale(DIGIT_NUMBER_AFTER_DOT, RoundingMode.HALF_UP);
        return PrepaidTaxResult.builder()
            .taxableIncome(taxableIncome)
            .taxRate(taxRate)
            .quickDeduction(quickDeduction)
            .tax(currentPeriodTax)
            .build();
    }
}
